<?php
/**
 * ===============================================
 * 版权所有 2019-2050 青岛铁锤科技有限公司，并保留所有权利。
 * 网站地址: http://www.huaxianling.com
 * ===============================================
 * Author: Happy dong
 * Created Time: 2019-06-27 17:38
 * Modified Time: 2019-06-27 17:38
 * Version: 2.0
 */

namespace App\Modules\Order\Services;


use App\Exceptions\AllValidatorException;
use App\Exceptions\NotFoundException;
use App\Lib\CreateStaticNumber;
use App\Modules\Employee\Repositories\EmployeeRepository;
use App\Modules\Employee\Repositories\EmployeeRoyaltyRepository;
use App\Modules\Member\Repositoryies\MemberRepository;
use App\Modules\MemberCard\Repositores\MemberCardFlowRepository;
use App\Modules\MemberCard\Repositores\MemberCardRepository;
use App\Modules\Message\Repositories\MessageRepository;
use App\Modules\Order\Repositories\OrderItemRepository;
use App\Modules\Order\Repositories\OrderRepository;
use App\Modules\Order\Repositories\RoyaltyRepository;
use App\Modules\Service\Repositories\ServiceRepository;
use App\Modules\Store\Repositories\StorePaymentRoyaltyRepository;
use App\Modules\Store\Repositories\StoreRepository;
use Flower\Core\Repository\Eloquent\BaseService;
use Illuminate\Support\Facades\DB;

class OfflineService extends BaseService
{
	private $serviceRepository;
	private $orderRepository;
	private $memberRepository;
	private $orderItemRepository;
	private $employeeRoyaltyRepository;
	private $royaltyRepository;
	private $cardRepository;
	private $memberCardFlowRepository;
	private $storePaymentRoyaltyRepository;
	private $employeeRepository;
	private $messageRepository;
	private $storeRepository;

	public function __construct(ServiceRepository $serviceRepository, OrderRepository $orderRepository, MemberRepository $memberRepository, OrderItemRepository $orderItemRepository, EmployeeRoyaltyRepository $employeeRoyaltyRepository, RoyaltyRepository $royaltyRepository, MemberCardRepository $cardRepository, MemberCardFlowRepository $memberCardFlowRepository, StorePaymentRoyaltyRepository $storePaymentRoyaltyRepository, EmployeeRepository $employeeRepository, MessageRepository $messageRepository, StoreRepository $storeRepository)
	{
		$this->serviceRepository = $serviceRepository;
		$this->orderRepository = $orderRepository;
		$this->memberRepository = $memberRepository;
		$this->orderItemRepository = $orderItemRepository;
		$this->employeeRoyaltyRepository = $employeeRoyaltyRepository;
		$this->royaltyRepository = $royaltyRepository;
		$this->cardRepository = $cardRepository;
		$this->memberCardFlowRepository = $memberCardFlowRepository;
		$this->storePaymentRoyaltyRepository = $storePaymentRoyaltyRepository;
		$this->employeeRepository = $employeeRepository;
		$this->messageRepository = $messageRepository;
		$this->storeRepository = $storeRepository;
	}

	/**
	 * 新增线下消费订单
	 * @param $barberId
	 * @param $storeId
	 * @param $serviceId
	 * @param $realPrice // 单价
	 * @param $isAppoint
	 * @param $source
	 * @param $memberId
	 * @param $count
	 * @param $changeReason
	 * @param $remark
	 * @param $memberCardId
	 * @param $payment
	 * @param $assistantId
	 * @return mixed
	 * @throws AllValidatorException
	 * @throws \App\Exceptions\NotFoundException
	 */
	public function addOffline($barberId, $storeId, $serviceId, $realPrice, $isAppoint, $source, $memberId, $count, $changeReason, $remark, $memberCardId, $payment, $assistantId)
	{
		if (isset($memberId)) {
			$this->memberRepository->isExisted($memberId);
		} else {
			$memberId = 0;
		}
		$memberCardId = empty($memberCardId) ? 0 : $this->cardRepository->isExisted($memberCardId)->id;
		// 验证服务是否存在
		$service = $this->serviceRepository->isExisted($serviceId);
		// 制作订单号
		$orderNo = CreateStaticNumber::makeNo('order');
		// 助理是否存在
		$assistantId = empty($assistantId) ? 0 : $this->employeeRepository->isExited($assistantId)->id;
		DB::beginTransaction();
		// 订单表插入
		$count = isset($count) ? $count : 1;
		$price = $service->price * $count;
		// 服务价格
		$totalRealPrice = isset($realPrice) ? round($realPrice * $count, 2) : null;

		// 存的服务单价 前台传递过来的
		$itemRealPrice = empty($realPrice) ? $service->price : $realPrice;
		$flag = true;

		// 计算消费金额
		if (($payment == config('constant.payment.member_card')) && !empty($memberCardId)) {
			$cardInfo = $this->cardRepository->isSuitableByServiceId($serviceId, $memberCardId);

			$cardDiscount = $cardInfo->cardTypeService->toArray();

			if (empty($cardDiscount)) {
				$cardDiscount = 100;
			} else {
				$cardDiscount = array_column($cardDiscount, null, 'service_id');
				$cardDiscount = isset($cardDiscount[$service->id]) ? $cardDiscount[$service->id]['discount'] : 100;
			}
			unset($cardInfo->cardTypeService);
			// 折扣金额
			$discountRealPrice = empty($totalRealPrice) ? round($price * $cardDiscount * 0.01, 2) : ((floatval($service->price) - floatval($realPrice) == 0) ? round($totalRealPrice * $cardDiscount * 0.01, 2) : $totalRealPrice);
			$itemRealPrice = (floatval($service->price) - floatval($itemRealPrice) == 0) ? round($itemRealPrice * $cardDiscount * 0.01, 2) : $itemRealPrice;

			if ($cardInfo->attribute == config('constant.memberCard.cardType.recharge')) {
				if ($cardInfo->balance < $discountRealPrice) {
					throw  new AllValidatorException(['msg' => '对不起，您的会员卡余额不足，请充值！当前余额为:' . $cardInfo->balance . '元']);
				}

				$cardInfo->balance -= $discountRealPrice;

				$consumptionInfo = "您本次消费：" . $cardInfo->balance . "元，会员卡余额：" . $discountRealPrice . "元";
			}

			if ($cardInfo->attribute == config('constant.memberCard.cardType.count')) {
				if ($cardInfo->count < $count) {
					throw  new AllValidatorException(['msg' => '对不起，您的次数卡剩余数不足，请充值！当前剩余次数为:' . $cardInfo->count . '次']);
				}
				$cardInfo->count -= $count;
				$consumptionInfo = "您本次消费：" . $cardInfo->count . "次，会员卡剩余可使用次数：" . $count . "次";
			}
			$cardInfo->save();
		} elseif (($payment == config('constant.payment.member_card')) && empty($memberCardId)) {
			throw  new NotFoundException(['msg' => '请选择需要支付的会员卡']);
		}

		$totalRealPrice = isset($discountRealPrice) ? $discountRealPrice : $totalRealPrice;
		// 订单表数据插入
		$order = $this->orderRepository->addNewOrderInfo($orderNo, $storeId, $barberId, 0, $price, $totalRealPrice, 0, $isAppoint, $source, $payment, $memberId, $memberCardId, 2, 1, 0, '', $assistantId, $changeReason, $remark);
		// 订单明细插入
		$orderItem = $this->orderItemRepository->addOrderItemInfo($order->id, $serviceId, $service->name, $service->price, $itemRealPrice, $count);

		// 查询理发师提成
		$userRoyaltyInfo = $this->employeeRoyaltyRepository->getBarberRoyaltyInfo($order->barber_id, $service->id);
		// 计算理发师提成
		$royalty = isset($userRoyaltyInfo) ? $userRoyaltyInfo->royalty : 0;
		// 计算助理提成
		$assistantRoyalty = isset($userRoyaltyInfo) ? $userRoyaltyInfo->assistant_royalty : 0;
		$paymentRoyalty = $this->storePaymentRoyaltyRepository->findByStoreId($order->store_id);
		$paymentList = array_flip(config('constant.payment'));
		//支付方式提成
		$paymentRoyalty = $paymentRoyalty[$paymentList[$payment]];
		// 写入提成表
		$res = $this->royaltyRepository->addOrderRoyalty($order->barber_id, $order->store_id, $order->id, $order->real_price, $royalty, $order->real_price, 1, $paymentRoyalty);

		// 计算店铺的纯利润
		$order->profit = $order->real_price - $res->amount;
		$order->save();

		if ($assistantId) {
			$asRoyalty = $this->royaltyRepository->addOrderRoyalty($assistantId, $order->store_id, $order->id, $order->real_price, $assistantRoyalty, $res->amount, 1);
			// 更新理发师提成
			$res->amount -= $asRoyalty->amount;
			$res->save();
		}
		if (($payment == config('constant.payment.member_card')) && !empty($memberCardId)) {
			$realPrice = $cardInfo->attribute == 1 ? $count : $totalRealPrice;
			$flowInfo = $this->memberCardFlowRepository->addFlowMemberCard($cardInfo->attribute, $memberCardId, $cardInfo->member_id, $barberId, $cardInfo->store_id, config('constant.memberCard.type.consume'), $order->id, $realPrice);
			$flag = empty($flowInfo) ? false : true;
		}
		// 会员卡 扣费

		$storeOrder = $this->orderRepository->getFinishedOrderNums($order->store_id);
		$this->storeRepository->updateStore($order->store_id, ['order_sum' => $storeOrder]);
		$result = (!empty($res) && !empty($order) && !empty($orderItem) && $flag);
		$result ? DB::commit() : DB::rollBack();

		return $order;
	}

}